using System.Windows;
using System.Windows.Controls;
using UltraLight.MVVM.Contracts;

namespace UltraLight.MVVM
{
    /// <summary>
    ///     Button command implementation
    /// </summary>
    public static class ButtonCommand
    {
        public static DependencyProperty CommandProperty =
            DependencyProperty.RegisterAttached("Command",
                                                typeof (IActionCommand<object>),
                                                typeof (ButtonCommand),
                                                new PropertyMetadata(null, CommandChanged));

        /// <summary>
        ///     Attach to the button and handle click and is enabled
        /// </summary>
        /// <param name="d"></param>
        /// <param name="e"></param>
        private static void CommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var button = d as Button;
            var command = e.NewValue as IActionCommand<object>;
            if (d == null || command == null) return;
            button.Click += (o, args) => command.Execute(GetCommandParameter((DependencyObject)o));
            command.CanExecuteChanged += (o, args) => button.IsEnabled = command.CanExecute(GetCommandParameter(d));
            button.IsEnabled = command.CanExecute(GetCommandParameter(d));
        }

        public static IActionCommand<object> GetCommand(DependencyObject obj)
        {
            return obj.GetValue(CommandProperty) as IActionCommand<object>;
        }

        public static void SetCommand(DependencyObject obj, IActionCommand<object> value)
        {
            obj.SetValue(CommandProperty, value);
        }

        /// <summary>
        ///     Parameter (optional)
        /// </summary>
        public static DependencyProperty CommandParameterProperty =
           DependencyProperty.RegisterAttached("CommandParameter",
                                               typeof(object),
                                               typeof(ButtonCommand),
                                               null);

        public static object GetCommandParameter(DependencyObject obj)
        {
            return obj.GetValue(CommandParameterProperty);
        }

        public static void SetCommandParameter(DependencyObject obj, object value)
        {
            obj.SetValue(CommandParameterProperty, value);
        }
    }
}